<template>
  <div class="sign-wrap">
    <a-form :model="formState" layout="vertical" class="sign-form">
      <div class="sign-form-top">
        <div class="sign-form-top-welcome">CDN 授权管理端</div>
      </div>
      <div class="sign-form-center">
        <a-form-item hide-label>
          <a-input
            v-model="formState.account"
            placeholder="请输入账号"
            class="!px-4"
            size="large"
            @change="accountError = ''">
            <template #prefix> <i-icons-account /> </template>
          </a-input>
        </a-form-item>
        <a-form-item hide-label>
          <section class="flex flex-col w-full gap-y-4">
            <a-input-password
              v-model.trim="formState.password"
              placeholder="请输入密码"
              class="!px-4"
              size="large"
              @change="accountError = ''"
              @keyup.enter="handleSubmit"
              @input="handlePasswordInput">
              <template #prefix> <i-icons-lock /> </template>
            </a-input-password>
            <div v-if="accountError" class="flex items-center gap-x-6px">
              <i-icons-danger />
              <span class="text-#ED3C3C text-sx/5">{{ accountError }}</span>
            </div>
          </section>
        </a-form-item>

        <a-button
          type="primary"
          size="large"
          class="w-full"
          :disabled="isDisabled"
          :loading="loading"
          @click="handleSubmit"
          >登录</a-button
        >
      </div>
      <div>
        <img src="@/assets/images/logo.png" class="w-[78px] h-5" calt="" />
      </div>
    </a-form>
    <visual-shield
      ref="visualShieldRef"
      :request="behavioralCaptcha"
      :verify="handleVerify" />
  </div>
</template>
<script lang="ts" setup>
import { useAppStore } from '@/stores/app'
import { ResultEnum } from '@/apis/http'
import {
  getAdminApiCaptchaImageApi,
  getAdminApiCaptchaPreCheckApi,
  postAdminApiCaptchaVerifyApi,
  postAdminApiLoginApi
} from '@/apis/modules/auth'
import {
  useBehavioralCaptcha,
  type RequestFnOptions,
  type VerifyOptions,
  type VisualShieldInstance
} from '@/components/visual-shield'
const visualShieldRef = ref<VisualShieldInstance>()
const router = useRouter()
const appStore = useAppStore()
const formState = reactive({
  account: '',
  password: ''
})
const behavioralCaptchaKey = ref('')
const accountError = ref<string>('')
const loading = ref(false)
const isDisabled = computed<boolean>(
  () =>
    !formState.password ||
    !formState.account ||
    loading.value ||
    !!accountError.value
)
const handleLogin = () => {
  loading.value = true
  const data = {
    account: formState.account,
    captcha_key: behavioralCaptchaKey.value,
    password: formState.password
  }
  postAdminApiLoginApi(data)
    .then((res: any) => {
      if (res.code === ResultEnum.SUCCESS) {
        appStore.saveToken(res.data.token)
        appStore.saveAccountInfo(res.data.account_info)
        accountError.value = ''
        router.replace('/')
      } else if (res.code === ResultEnum.WRONGPASSWORD) {
        accountError.value =
          res.message ??
          '请输入8-20个字符，需包含大小写英文字母、数字和标点符号（除空格）,请重试'
      } else if (res.code === ResultEnum.PASSWORDERROR) {
        accountError.value = res.message ?? '账号或密码不正确,请重试'
      } else if (res.code === ResultEnum.WRONGACCOUNTERROR) {
        accountError.value =
          res.message ?? '请输入4-18个字符，可包含英文字母、数字、下划线'
      } else {
        Message.error({
          content: res.message
        })
      }
    })
    .finally(() => (loading.value = false))
}

const { withInterceptor } = useBehavioralCaptcha(visualShieldRef, handleLogin)

// 生成行为验证码
const behavioralCaptcha = ({
  loading,
  onSuccess,
  onError,
  onFrequent
}: RequestFnOptions) => {
  loading.value = true
  getAdminApiCaptchaImageApi()
    .then((res: any) => {
      if (Number(res.code) === ResultEnum.SUCCESS) {
        const { image_base64, thumb_base64, key } = Object.assign(
          { image_base64: '', thumb_base64: '', key: '' },
          res.data
        )
        onSuccess(image_base64, thumb_base64)
        behavioralCaptchaKey.value = key
      } else if (Number(res.code) === ResultEnum.FREQUENTREQUEST) {
        onFrequent(res?.message)
        const { key } = Object.assign(
          { image_base64: '', thumb_base64: '', key: '' },
          res.data
        )
        behavioralCaptchaKey.value = key
      } else {
        onError(res.message)
      }
    })
    .finally(() => (loading.value = false))
}

// 验证验证码
const handleVerify = ({ onError, onSuccess, points }: VerifyOptions) => {
  postAdminApiCaptchaVerifyApi({
    key: behavioralCaptchaKey.value,
    dots: String(points)
  }).then((res: any) => {
    if (Number(res.code) === ResultEnum.SUCCESS) {
      onSuccess()
    } else {
      onError(res.message)
    }
  })
}
const handlePasswordInput = (val: string) => {
  formState.password = val.replace(/\s/g, '')
  accountError.value = ''
}
const handleSubmit = async () => {
  if (isDisabled.value) return
  getAdminApiCaptchaPreCheckApi({})
    .then((res) => {
      const needCaptcha = res?.need_captcha
      if (needCaptcha) {
        withInterceptor()
      } else {
        handleLogin()
      }
    })
    .catch(() => {
      withInterceptor()
    })
}
</script>
<style lang="less" scoped>
.sign-wrap {
  width: 100%;
  height: 100%;
  background: url('@/assets/images/login-bg.png') repeat;
  background-size: cover;
  justify-content: center;
  align-items: center;
}
:deep(.sign-form) {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: #fff;
  box-shadow: 0.125rem 0.125rem 3.125rem 0 rgba(58, 58, 58, 0.04);
  display: flex;
  width: 550px;
  padding: 80px 88px 40px 88px;
  flex-direction: column;
  align-items: center;
  gap: 64px;
  flex-shrink: 0;
  border-radius: 24px;
  border: 1px solid #fff;
  background: linear-gradient(180deg, #fff 0%, rgba(255, 255, 255, 0.5) 100%);
  backdrop-filter: blur(20px);

  .sign-form-top {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    align-self: stretch;
    .sign-form-top-welcome {
      color: var(---color-text-1, #1d2129);
      font-size: 28px;
      font-weight: 700;
      line-height: 36px; /* 128.571% */
    }
    .sign-form-top-title {
      color: var(---color-text-1, #1d2129);
      font-size: 16px;
      font-weight: 400;
      line-height: 24px; /* 150% */
    }
  }
  .sign-form-center {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 32px;
    align-self: stretch;
    .arco-form-item {
      margin-bottom: 0;
    }
    .arco-input {
      height: 48px;
    }
    .arco-btn {
      height: 48px;
    }
  }
}
</style>
